package com.sise.cn.task.exception;

import com.sise.cn.task.enumerate.ServerResponseEnum;
import com.sise.cn.task.vo.ServerResponseVO;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * 全局异常处理
 *
 * @author 龚秀峰
 * @date 2019-10-18
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private final Logger logger = LogManager.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理其他未知异常
     *
     * @param e 异常
     * @return 统一异常响应信息
     */
    @ExceptionHandler({Exception.class})
    public ServerResponseVO<String> globalExceptionHandler(Exception e) {
        if(e instanceof HttpMessageNotReadableException){
            this.logger.error("JSON转换异常：", e);
            return ServerResponseVO.error(e.getMessage());
        }
        this.logger.error("未知异常：", e);
        return ServerResponseVO.error(ServerResponseEnum.ERROR);
    }

    /**
     * 处理所有业务异常
     *
     * @param e 异常
     * @return 业务异常响应信息
     */
    @ExceptionHandler({BaseBusinessException.class})
    public ServerResponseVO<String> businessExceptionHandler(BaseBusinessException e) {
        this.logger.error("业务异常：", e);
        return ServerResponseVO.error(ServerResponseEnum.BUSINESS_EXCEPTION);
    }

    /**
     * 处理处方单业务异常
     *
     * @param e 异常
     * @return 业务异常响应信息
     */
    @ExceptionHandler({TaskException.class})
    @ResponseStatus(HttpStatus.OK)
    public ServerResponseVO<String> businessExceptionHandler(TaskException e) {
        this.logger.error("Task模块异常：", e);
        return ServerResponseVO.error(e.getResponseEnum());
    }

    /**
     * 拦截表单参数校验
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({BindException.class})
    public ServerResponseVO<String> bindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        return ServerResponseVO.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }

    /**
     * 拦截JSON参数校验
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ServerResponseVO<String> bindException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        return ServerResponseVO.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    }


}
